package com.engine.salary.web;

import com.engine.common.util.ServiceUtil;
import com.engine.salary.entity.salaryarchive.dto.*;
import com.engine.salary.entity.salaryarchive.param.*;
import com.engine.salary.enums.salaryarchive.SalaryArchiveImportTypeEnum;
import com.engine.salary.enums.salaryarchive.SalaryArchiveListTypeEnum;
import com.engine.salary.enums.salaryarchive.SalaryArchiveStatusEnum;
import com.engine.salary.util.ResponseResult;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.wrapper.SalaryArchiveItemWrapper;
import com.engine.salary.wrapper.SalaryArchiveTaxAgentWrapper;
import com.engine.salary.wrapper.SalaryArchiveWrapper;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import weaver.hrm.HrmUserVarify;
import weaver.hrm.User;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.StreamingOutput;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 薪资档案
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
@Slf4j
public class SalaryArchiveController {
    private SalaryArchiveWrapper getSalaryArchiveWrapper(User user) {
        return ServiceUtil.getService(SalaryArchiveWrapper.class, user);
    }

    private SalaryArchiveItemWrapper getSalaryArchiveItemWrapper(User user) {
        return ServiceUtil.getService(SalaryArchiveItemWrapper.class, user);
    }

    private SalaryArchiveTaxAgentWrapper getSalaryArchiveTaxAgentWrapper(User user) {
        return ServiceUtil.getService(SalaryArchiveTaxAgentWrapper.class, user);
    }


//    /******** 薪资档案主表 start ***********************************************************************************************/


    /**
     * 获取各tab总人数
     *
     * @param request
     * @param response
     * @return
     */
    @GET
    @Path("/queryTabTotal")
    @Produces(MediaType.APPLICATION_JSON)
    public String queryTabTotal(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveQueryParam, Map<String, Long>>(user).run(getSalaryArchiveWrapper(user)::queryTabTotal);
    }


    /**
     * 待定薪列表
     *
     * @return
     */
    @POST
    @Path("/pendingList")
    @Produces(MediaType.APPLICATION_JSON)
    public String pendingList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveQueryParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::pendingList, queryParam);
    }


    /**
     * 设为定薪员工
     *
     * @param ids
     * @return
     */
    @POST
    @Path("/gotoFixed")
    @Produces(MediaType.APPLICATION_JSON)
    public String gotoFixed(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::gotoFixed, ids);
    }


    /**
     * 一键全部设为定薪员工
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/allGotoFixed")
    @Produces(MediaType.APPLICATION_JSON)
    public String allGotoFixed(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveQueryParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::allGotoFixed, queryParam);
    }


    /**
     * 删除待定薪待办
     *
     * @param ids
     * @return
     */
    @POST
    @Path("/deletePendingTodo")
    @Produces(MediaType.APPLICATION_JSON)
    public String deletePendingTodo(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, String>(user).run(getSalaryArchiveWrapper(user)::deletePendingTodo, ids);
    }

    /**
     * 删除薪资档案（待定薪、停薪来自待定薪）
     *
     * @param ids
     * @return
     */
    @POST
    @Path("/deleteSalaryArchive")
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteSalaryArchive(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, String>(user).run(getSalaryArchiveWrapper(user)::deleteSalaryArchive, ids);
    }


    /**
     * 发薪列表
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/fixedList")
    @Produces(MediaType.APPLICATION_JSON)
    public String fixedList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveQueryParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::fixedList, queryParam);
    }


    /**
     * 待停薪列表
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/suspendList")
    @Produces(MediaType.APPLICATION_JSON)
    public String suspendList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveQueryParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::suspendList, queryParam);
    }

    /**
     * 停薪
     *
     * @param ids
     * @return
     */
    @POST
    @Path("/gotoStop")
    @Produces(MediaType.APPLICATION_JSON)
    public String gotoStop(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::gotoStop, ids);
    }


    /**
     * 一键全部停薪
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/allGotoStop")
    @Produces(MediaType.APPLICATION_JSON)
    public String allGotoStop(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveQueryParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::allGotoStop, queryParam);
    }


    /**
     * 删除待停薪待办
     *
     * @param ids
     * @return
     */
    @POST
    @Path("/deleteSuspendTodo")
    @Produces(MediaType.APPLICATION_JSON)
    public String stopList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, String>(user).run(getSalaryArchiveWrapper(user)::deleteSuspendTodo, ids);
    }

    /**
     * 停薪列表
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/stopList")
    @Produces(MediaType.APPLICATION_JSON)
    public String stopList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveQueryParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::stopList, queryParam);
    }

    /**
     * 外部人员列表
     *
     * @param request
     * @param response
     * @param queryParam
     * @return
     */
    @POST
    @Path("/extList")
    @Produces(MediaType.APPLICATION_JSON)
    public String extList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveQueryParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::extList, queryParam);
    }


    /**
     * 取消停薪
     *
     * @param ids
     * @return
     */
    @POST
    @Path("/cancelStop")
    @Produces(MediaType.APPLICATION_JSON)
    public String cancelStop(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody Collection<Long> ids) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Collection<Long>, String>(user).run(getSalaryArchiveWrapper(user)::cancelStop, ids);
    }


    /**
     * 薪资档案列表
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/list")
    @Produces(MediaType.APPLICATION_JSON)
    public String list(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveQueryParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::listPage, queryParam);
    }

    /**
     * 导出薪资档案
     *
     * @return
     */
    @GET
    @Path("/exportList")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response exportList(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        try {
            User user = HrmUserVarify.getUser(request, response);
            SalaryArchiveQueryParam queryParam = buildParam(request);

            XSSFWorkbook workbook = getSalaryArchiveWrapper(user).exportList(queryParam);

            String fileName = "薪资档案" + LocalDate.now();
            try {
                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            StreamingOutput output = outputStream -> {
                workbook.write(outputStream);
                outputStream.flush();
            };

            response.setContentType("application/octet-stream");
            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();
        } catch (Exception e) {
            log.error("薪资档案导出异常", e);
            throw e;
        }

    }

    /**
     * 获取薪资档案详情表单
     *
     * @return
     */
    @GET
    @Path("/getForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getFrom(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        String salaryArchiveIdStr = request.getParameter("salaryArchiveId");
        Long salaryArchiveId = null;
        if (StringUtils.isNotBlank(salaryArchiveIdStr)) {
            salaryArchiveId = Long.valueOf(salaryArchiveIdStr);
        }
        return new ResponseResult<Long, SalaryArchiveFormDTO>(user).run(getSalaryArchiveWrapper(user)::getFrom, salaryArchiveId);
    }


    /**
     * 保存发薪设置
     *
     * @param saveParam
     * @return
     */
    @POST
    @Path("/savePaySet")
    @Produces(MediaType.APPLICATION_JSON)
    public String savePaySet(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveSetPaySaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveSetPaySaveParam, String>(user).run(getSalaryArchiveWrapper(user)::savePaySet, saveParam);
    }


    /**
     * 获取离职时段设置表单
     *
     * @return
     */
    @GET
    @Path("/getDimissionSetForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getDimissionSetForm(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::getDimissionSetForm);
    }

    /**
     * 保存离职时段设置
     *
     * @return
     */
    @POST
    @Path("/saveDimissionSet")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveDimissionSet(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveDimissionSaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveDimissionSaveParam, String>(user).run(getSalaryArchiveWrapper(user)::saveDimissionSet, saveParam);
    }

    /**
     * 获取导入类型
     *
     * @return
     */
    @GET
    @Path("/getImportTypes")
    @Produces(MediaType.APPLICATION_JSON)
    public String getImportTypes(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long, List<Map<String, Object>>>(user).run(getSalaryArchiveWrapper(user)::getImportTypes);
    }

    /**
     * 下载导入模板
     *
     * @return
     */
    @GET
    @Path("/downloadTemplate")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response downloadTemplate(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        try {
            User user = HrmUserVarify.getUser(request, response);
            SalaryArchiveQueryParam queryParam = buildParam(request);

            XSSFWorkbook workbook = getSalaryArchiveWrapper(user).downloadTemplate(queryParam);

            SalaryArchiveListTypeEnum listTypeEnum = queryParam.getListType();

            // 待定薪列表
            boolean isPendingList = listTypeEnum == SalaryArchiveListTypeEnum.PENDING;
            // 定薪列表
            boolean isFixedList = listTypeEnum == SalaryArchiveListTypeEnum.FIXED;
            // 待停薪列表
            boolean isSuspendList = listTypeEnum == SalaryArchiveListTypeEnum.SUSPEND;
            if (isPendingList) {
                queryParam.setRunStatusList(Arrays.asList(SalaryArchiveStatusEnum.PENDING.getValue()));
            } else if (isFixedList) {
                queryParam.setRunStatusList(Arrays.asList(SalaryArchiveStatusEnum.FIXED.getValue(), SalaryArchiveStatusEnum.SUSPEND.getValue()));
            } else if (isSuspendList) {
                queryParam.setRunStatusList(Arrays.asList(SalaryArchiveStatusEnum.SUSPEND.getValue()));
            }

            boolean isInit = SalaryArchiveImportTypeEnum.INIT.getValue().equals(queryParam.getImportType());
            boolean isSalaryItemAdjust = SalaryArchiveImportTypeEnum.SALARYITEMADJUST.getValue().equals(queryParam.getImportType());
            boolean isExtEmp = queryParam.isExtSalaryArchiveList();

            // 名称
            String finalNameI18n = SalaryI18nUtil.getI18nLabel(101601, "薪资档案导入模板-")
                    + SalaryI18nUtil.getI18nLabel(listTypeEnum.getLabelId(), listTypeEnum.getDefaultLabel());
            if (isExtEmp) {
                finalNameI18n += "-非系统人员";
            }

            if (isFixedList) {
                // 初始化
                if (isInit) {
                    finalNameI18n +=
                            "-" + SalaryI18nUtil.getI18nLabel(SalaryArchiveImportTypeEnum.INIT.getLabelId(), SalaryArchiveImportTypeEnum.INIT.getDefaultLabel());
                    // 调薪
                } else if (isSalaryItemAdjust) {
                    finalNameI18n += "-" + SalaryI18nUtil
                            .getI18nLabel(SalaryArchiveImportTypeEnum.SALARYITEMADJUST.getLabelId(), SalaryArchiveImportTypeEnum.SALARYITEMADJUST.getDefaultLabel());
                }
            }

            String fileName = finalNameI18n + LocalDate.now();

            try {
                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            StreamingOutput output = outputStream -> {
                workbook.write(outputStream);
                outputStream.flush();
            };

            response.setContentType("application/octet-stream");
            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();
        } catch (Exception e) {
            log.error("薪资档案导入模板导出异常", e);
            throw e;
        }
    }

    @Nullable
    private SalaryArchiveQueryParam buildParam(HttpServletRequest request) {
        SalaryArchiveQueryParam param = new SalaryArchiveQueryParam();
        String ids = request.getParameter("ids");
        if (StringUtils.isNotBlank(ids)) {
            param.setIds(Arrays.stream(ids.split(",")).map(Long::valueOf).collect(Collectors.toList()));
        }
        String username = request.getParameter("username");
        if (StringUtils.isNotBlank(username)) {
            param.setUsername(username);
        }
        String workcode = request.getParameter("workcode");
        if (StringUtils.isNotBlank(workcode)) {
            param.setWorkcode(workcode);
        }
        String taxAgentId = request.getParameter("taxAgentId");
        if (StringUtils.isNotBlank(taxAgentId)) {
            param.setTaxAgentId(Long.valueOf(taxAgentId));
        }
        String taxAgentIdsStr = request.getParameter("taxAgentIds");
        if (StringUtils.isNotBlank(taxAgentIdsStr)) {
            List<Long> taxAgentIds = Arrays.stream(taxAgentIdsStr.split(",")).filter(NumberUtils::isCreatable).map(Long::valueOf).collect(Collectors.toList());
            param.setTaxAgentIds(taxAgentIds);
        }
        String departmentIds = request.getParameter("departmentIds");
        if (StringUtils.isNotBlank(departmentIds)) {
            param.setDepartmentIds(Arrays.stream(departmentIds.split(",")).map(Long::valueOf).collect(Collectors.toList()));
        }
        String subcompanyIds = request.getParameter("subcompanyIds");
        if (StringUtils.isNotBlank(subcompanyIds)) {
            param.setSubcompanyIds(Arrays.stream(subcompanyIds.split(",")).map(Long::valueOf).collect(Collectors.toList()));
        }
        String positionIds = request.getParameter("positionIds");
        if (StringUtils.isNotBlank(positionIds)) {
            param.setPositionIds(Arrays.stream(positionIds.split(",")).map(Long::valueOf).collect(Collectors.toList()));
        }
        String userstatus = request.getParameter("userstatus");
        if (StringUtils.isNotBlank(userstatus)) {
            param.setUserstatus(userstatus);
        }
        String statuses = request.getParameter("statuses");
        if (StringUtils.isNotBlank(statuses)) {
            param.setStatuses(Arrays.stream(statuses.split(",")).map(String::valueOf).collect(Collectors.toList()));
        }
        String hiredate = request.getParameter("hiredate");
        if (StringUtils.isNotBlank(hiredate)) {
            param.setHiredate(Arrays.asList(hiredate.split(",")));
        }
        String importType = request.getParameter("importType");
        param.setImportType(importType);
        String hasData = request.getParameter("hasData");
        if (StringUtils.isNotBlank(hasData)) {
            param.setHasData(Boolean.valueOf(hasData));
        }
        String archiveStatus = request.getParameter("archiveStatus");
        if (StringUtils.isNotBlank(archiveStatus)) {
            param.setArchiveStatus(archiveStatus);
        }
        String runStatusLists = request.getParameter("runStatusList");
        if (StringUtils.isNotBlank(runStatusLists)) {
            param.setRunStatusList(Arrays.stream(runStatusLists.split(",")).collect(Collectors.toList()));
        }
        String listType = request.getParameter("listType");
        if (StringUtils.isNotBlank(listType)) {
            param.setListType(SalaryArchiveListTypeEnum.parseByValue(listType));
        }
        //1标识外部人员
        String extSalaryArchiveList = request.getParameter("extSalaryArchiveList");
        if (StringUtils.isNotBlank(extSalaryArchiveList)) {
            param.setExtSalaryArchiveList("true".equals(extSalaryArchiveList));
        }
        String payStartDateStartDateStr = request.getParameter("payStartDateStartDateStr");
        if (StringUtils.isNotBlank(payStartDateStartDateStr) && SalaryDateUtil.checkDay(payStartDateStartDateStr)) {
            param.setPayStartDateStartDate(SalaryDateUtil.stringToDate(payStartDateStartDateStr));
        }
        String payStartDateEndDateStr = request.getParameter("payStartDateEndDateStr");
        if (StringUtils.isNotBlank(payStartDateEndDateStr) && SalaryDateUtil.checkDay(payStartDateEndDateStr)) {
            param.setPayStartDateEndDate(SalaryDateUtil.stringToDate(payStartDateEndDateStr));
        }
        String payEndDateStartDateStr = request.getParameter("payEndDateStartDateStr");
        if (StringUtils.isNotBlank(payEndDateStartDateStr) && SalaryDateUtil.checkDay(payEndDateStartDateStr)) {
            param.setPayEndDateStartDate(SalaryDateUtil.stringToDate(payEndDateStartDateStr));
        }
        String payEndDateEndDateStr = request.getParameter("payEndDateEndDateStr");
        if (StringUtils.isNotBlank(payEndDateEndDateStr) && SalaryDateUtil.checkDay(payEndDateEndDateStr)) {
            param.setPayEndDateEndDate(SalaryDateUtil.stringToDate(payEndDateEndDateStr));
        }
        String adjustSalaryStartDateStr = request.getParameter("adjustSalaryStartDate");
        if (StringUtils.isNotBlank(adjustSalaryStartDateStr) && SalaryDateUtil.checkDay(adjustSalaryStartDateStr)) {
            param.setAdjustSalaryStartDate(SalaryDateUtil.stringToDate(adjustSalaryStartDateStr));
        }
        String adjustSalaryEndDate = request.getParameter("adjustSalaryEndDate");
        if (StringUtils.isNotBlank(adjustSalaryEndDate) && SalaryDateUtil.checkDay(adjustSalaryEndDate)) {
            param.setAdjustSalaryEndDate(SalaryDateUtil.stringToDate(adjustSalaryEndDate));
        }
        return param;
    }


    @POST
    @Path("/preview")
    @Produces(MediaType.APPLICATION_JSON)
    public String preview(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveImportHandleParam importParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveImportHandleParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::preview, importParam);
    }

    /**
     * 导入薪资档案附件上传前置校验
     *
     * @param importParam
     * @return
     */
    @POST
    @Path("/checkImportSalaryArchive")
    @Produces(MediaType.APPLICATION_JSON)
    public String checkImportSalaryArchive(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveImportHandleParam importParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveImportHandleParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::checkImportSalaryArchiveParam, importParam);
    }

    //导入
    @POST
    @Path("/importSalaryArchive")
    @Produces(MediaType.APPLICATION_JSON)
    public String importSalaryArchive(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveImportHandleParam importParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveImportHandleParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::importSalaryArchive, importParam);
    }

    //人员状态列表
    @GET
    @Path("/searchCondition")
    @Produces(MediaType.APPLICATION_JSON)
    public String searchCondition(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SingleTaxAgentAdjustRecordQueryParam, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::searchCondition);
    }

    //停薪
    @POST
    @Path("/stopSalary")
    @Produces(MediaType.APPLICATION_JSON)
    public String stopSalary(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveStopParam stopSalaryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveStopParam, String>(user).run(getSalaryArchiveWrapper(user)::stopSalary, stopSalaryParam);
    }

    /**
     * 同步所有档案起始发薪日期变为入职日期
     *
     * @return
     */
    @GET
    @Path("/syncPayStartDate")
    @Produces(MediaType.APPLICATION_JSON)
    public String syncPayStartDate(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Void, String>(user).run(getSalaryArchiveWrapper(user)::syncPayStartDate);
    }

    // ******** 薪资档案主表 end ***********************************************************************************************/

    // ******** 薪资项目调整 start ***********************************************************************************************/

    /**
     * 获取薪资项目调整表单
     *
     * @return
     */
    @GET
    @Path("/getSalaryItemForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSalaryItemForm(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        String salaryArchiveIdStr = request.getParameter("salaryArchiveId");
        Long salaryArchiveId = null;
        if (StringUtils.isNotBlank(salaryArchiveIdStr)) {
            salaryArchiveId = Long.valueOf(salaryArchiveIdStr);
        }
        return new ResponseResult<Long, SalaryArchiveItemFormDTO>(user).run(getSalaryArchiveItemWrapper(user)::getSalaryItemForm, salaryArchiveId);
    }


    /**
     * 获取薪资项目调整前的值
     *
     * @param adjustBeforeParam
     * @return
     */
    @POST
    @Path("/getSalaryItemAdjustBeforeValue")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSalaryItemAdjustBeforeValue(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryItemAdjustBeforeParam adjustBeforeParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryItemAdjustBeforeParam, String>(user).run(getSalaryArchiveItemWrapper(user)::getSalaryItemAdjustBeforeValue, adjustBeforeParam);
    }

    /**
     * 通过薪资档案的薪资项目id获取薪资项目调整表单
     *
     * @return
     */
    @GET
    @Path("/getSalaryItemFormBySalaryArchiveItemId")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSalaryItemFormBySalaryArchiveItemId(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        String salaryArchiveItemIdStr = request.getParameter("salaryArchiveItemId");
        Long salaryArchiveItemId = null;
        if (StringUtils.isNotBlank(salaryArchiveItemIdStr)) {
            salaryArchiveItemId = Long.valueOf(salaryArchiveItemIdStr);
        }
        return new ResponseResult<Long, SalaryArchiveItemFormDTO>(user).run(getSalaryArchiveItemWrapper(user)::getSalaryItemFormBySalaryArchiveItemId, salaryArchiveItemId);
    }

    /**
     * 保存薪资项目调整前校验
     */
    @POST
    @Path("/checkSaveSalaryItem")
    @Produces(MediaType.APPLICATION_JSON)
    public String checkSaveSalaryItem(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveItemSaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveItemSaveParam, String>(user).run(getSalaryArchiveItemWrapper(user)::checkSaveSalaryItem, saveParam);
    }


    /**
     * 保存薪资项目调整
     */
    @POST
    @Path("/saveSalaryItem")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveSalaryItem(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveItemSaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveItemSaveParam, String>(user).run(getSalaryArchiveItemWrapper(user)::saveSalaryItem, saveParam);
    }


    /**
     * 删除薪资项目调整
     */
    @GET
    @Path("/deleteSalaryItem")
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteSalaryItem(@Context HttpServletRequest request, @Context HttpServletResponse response, @QueryParam(value = "salaryArchiveItemId") Long salaryArchiveItemId) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long, String>(user).run(getSalaryArchiveItemWrapper(user)::deleteSalaryItem, salaryArchiveItemId);
    }

    // ******** 薪资项目调整 end ***********************************************************************************************/

    // ******** 个税扣缴义务人调整 start ***********************************************************************************************/

    /**
     * 获取个税扣缴义务人调整表单
     *
     * @param salaryArchiveId
     * @return
     */
    @GET
    @Path("/getTaxAgentForm")
    @Produces(MediaType.APPLICATION_JSON)
    public String getTaxAgentForm(@Context HttpServletRequest request, @Context HttpServletResponse response, @QueryParam(value = "salaryArchiveId") Long salaryArchiveId) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long, SalaryArchiveTaxAgentFormDTO>(user).run(getSalaryArchiveTaxAgentWrapper(user)::getTaxAgentForm, salaryArchiveId);
    }

    /**
     * 通过薪资档案的个税扣缴义务人id获取个税扣缴义务人调整表单`
     *
     * @param salaryArchiveTaxAgentId
     * @return
     */
    @GET
    @Path("/getTaxAgentFormBySalaryArchiveTaxAgentId")
    @Produces(MediaType.APPLICATION_JSON)
    public String getTaxAgentFormBySalaryArchiveTaxAgentId(@Context HttpServletRequest request, @Context HttpServletResponse response, @QueryParam(value = "salaryArchiveTaxAgentId") Long salaryArchiveTaxAgentId) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long, SalaryArchiveTaxAgentFormDTO>(user).run(getSalaryArchiveTaxAgentWrapper(user)::getTaxAgentFormBySalaryArchiveTaxAgentId, salaryArchiveTaxAgentId);
    }


    /**
     * 保存个税扣缴义务人调整
     *
     * @param saveParam
     * @return
     */
    @POST
    @Path("/saveTaxAgent")
    @Produces(MediaType.APPLICATION_JSON)
    public String saveTaxAgent(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveTaxAgentSaveParam saveParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveTaxAgentSaveParam, String>(user).run(getSalaryArchiveTaxAgentWrapper(user)::saveTaxAgent, saveParam);
    }


    /**
     * 删除个税扣缴义务人调整
     *
     * @param salaryArchiveTaxAgentId
     * @return
     */
    @GET
    @Path("/deleteTaxAgent")
    @Produces(MediaType.APPLICATION_JSON)
    public String deleteTaxAgent(@Context HttpServletRequest request, @Context HttpServletResponse response, @QueryParam(value = "salaryArchiveTaxAgentId") Long salaryArchiveTaxAgentId) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<Long, String>(user).run(getSalaryArchiveTaxAgentWrapper(user)::deleteTaxAgent, salaryArchiveTaxAgentId);
    }

    // ******** 薪资项目调整 end ***********************************************************************************************/

    // ******** 薪资项目调整记录 start ***********************************************************************************************/


    /**
     * 薪资项目调整记录列表
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/adjustRecord/salaryItemList")
    @Produces(MediaType.APPLICATION_JSON)
    public String adjustRecordList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryItemAdjustRecordQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryItemAdjustRecordQueryParam, PageInfo<SalaryItemAdjustRecordListDTO>>(user).run(getSalaryArchiveItemWrapper(user)::adjustRecordList, queryParam);
    }

    /**
     * 单个档案的薪资项目调整记录列表
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/adjustRecord/singleSalaryItemList")
    @Produces(MediaType.APPLICATION_JSON)
    public String singleSalaryItemAdjustRecordList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SingleSalaryItemAdjustRecordQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SingleSalaryItemAdjustRecordQueryParam, PageInfo<SingleSalaryItemAdjustRecordListDTO>>(user).run(getSalaryArchiveItemWrapper(user)::singleSalaryItemAdjustRecordList, queryParam);
    }


    /**
     * @return String
     * @description 编辑前获取薪资项目调整信息
     * @author Harryxzy
     * @date 2022/11/15 9:25
     */
    @POST
    @Path("/adjustRecord/getSingleSalaryItemInfo")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSingleSalaryItemInfo(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SingleSalaryItemAdjustRecordListDTO queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SingleSalaryItemAdjustRecordListDTO, SalaryArchiveItemFormDTO>(user).run(getSalaryArchiveItemWrapper(user)::getSingleSalaryItemInfo, queryParam);
    }

    /**
     * @return String
     * @description 单个档案的薪资项目调整的编辑
     * @author Harryxzy
     * @date 2022/11/11 13:50
     */
    @POST
    @Path("/adjustRecord/editSingleSalaryItem")
    @Produces(MediaType.APPLICATION_JSON)
    public String editSingleSalaryItem(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SalaryArchiveItemSaveParam updateParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SalaryArchiveItemSaveParam, String>(user).run(getSalaryArchiveItemWrapper(user)::editSingleSalaryItem, updateParam);
    }


    /**
     * 导出薪资项目调整记录列表
     */
    @GET
    @Path("/adjustRecord/exportSalaryItemList")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response exportSalaryItemList(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        try {
            User user = HrmUserVarify.getUser(request, response);

            SalaryItemAdjustRecordQueryParam param = getSalaryItemAdjustRecordQueryParam(request);

            XSSFWorkbook workbook = getSalaryArchiveItemWrapper(user).exportAdjustRecordList(param);

            String fileName = "薪资项目调整记录" + LocalDate.now();

            try {
                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            StreamingOutput output = outputStream -> {
                workbook.write(outputStream);
                outputStream.flush();
            };

            response.setContentType("application/octet-stream");
            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();

        } catch (Exception e) {
            log.error("薪资项目调整记录导出异常", e);
            throw e;
        }

    }

    @NotNull
    private SalaryItemAdjustRecordQueryParam getSalaryItemAdjustRecordQueryParam(HttpServletRequest request) {
        SalaryItemAdjustRecordQueryParam param = new SalaryItemAdjustRecordQueryParam();
        String ids = request.getParameter("ids");
        if (StringUtils.isNotBlank(ids)) {
            param.setIds(Arrays.stream(ids.split(",")).map(Long::valueOf).collect(Collectors.toList()));
        }
        String salaryArchiveId = request.getParameter("salaryArchiveId");
        if (StringUtils.isNotBlank(salaryArchiveId)) {
            param.setSalaryArchiveId(Long.parseLong(salaryArchiveId));
        }
        String keyword = request.getParameter("keyword");
        if (StringUtils.isNotBlank(keyword)) {
            param.setKeyword(keyword);
        }
        String username = request.getParameter("username");
        if (StringUtils.isNotBlank(username)) {
            param.setUsername(username);
        }
        String employeeId = request.getParameter("employeeId");
        if (StringUtils.isNotBlank(employeeId)) {
            param.setSalaryArchiveId(Long.parseLong(employeeId));
        }
        String departmentIds = request.getParameter("departmentIds");
        if (StringUtils.isNotBlank(departmentIds)) {
            param.setDepartmentIds(Arrays.stream(departmentIds.split(",")).map(Long::valueOf).collect(Collectors.toList()));
        }
        String positionIds = request.getParameter("positionIds");
        if (StringUtils.isNotBlank(positionIds)) {
            param.setPositionIds(Arrays.stream(positionIds.split(",")).map(Long::valueOf).collect(Collectors.toList()));
        }
        String userstatus = request.getParameter("userstatus");
        if (StringUtils.isNotBlank(userstatus)) {
            param.setUserstatus(userstatus);
        }
        String adjustItem = request.getParameter("adjustItem");
        if (StringUtils.isNotBlank(adjustItem)) {
            param.setAdjustItem(adjustItem);
        }
        String adjustReason = request.getParameter("adjustReason");
        if (StringUtils.isNotBlank(adjustReason)) {
            param.setAdjustReason(adjustReason);
        }

        String effectiveTime = request.getParameter("effectiveTime");
        if (StringUtils.isNotBlank(effectiveTime)) {
            List<Date> collect = Arrays.stream(effectiveTime.split(",")).map(time -> SalaryDateUtil.parse(time, SalaryDateUtil.DATE_FORMATTER_PATTERN)).collect(Collectors.toList());
            param.setEffectiveTime(collect);
        }

        String operateTime = request.getParameter("operateTime");
        if (StringUtils.isNotBlank(operateTime)) {
            List<Date> collect = Arrays.stream(operateTime.split(",")).map(time -> SalaryDateUtil.parse(time, SalaryDateUtil.DATE_FORMATTER_PATTERN)).collect(Collectors.toList());
            param.setOperateTime(collect);
        }

        String operatorIds = request.getParameter("operatorIds");
        if (StringUtils.isNotBlank(operatorIds)) {
            param.setOperatorIds(Arrays.stream(operatorIds.split(",")).map(Long::valueOf).collect(Collectors.toList()));
        }

        String description = request.getParameter("description");
        if (StringUtils.isNotBlank(description)) {
            param.setUserstatus(description);
        }
        return param;
    }

    /******** 薪资项目调整记录 end ***********************************************************************************************/

    /******** 个税扣缴义务人调整记录 start ***********************************************************************************************/

    /**
     * 个税扣缴义务人调整记录列表
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/adjustRecord/taxAgentList")
    @Produces(MediaType.APPLICATION_JSON)
    public String taxAgentList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody TaxAgentAdjustRecordQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<TaxAgentAdjustRecordQueryParam, PageInfo<TaxAgentAdjustRecordListDTO>>(user).run(getSalaryArchiveTaxAgentWrapper(user)::adjustRecordList, queryParam);
    }

    /**
     * 单个档案的个税扣缴义务人调整记录列表
     *
     * @param queryParam
     * @return
     */
    @POST
    @Path("/adjustRecord/singleTaxAgentList")
    @Produces(MediaType.APPLICATION_JSON)
    public String SingleTaxAgentAdjustRecordList(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody SingleTaxAgentAdjustRecordQueryParam queryParam) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<SingleTaxAgentAdjustRecordQueryParam, PageInfo<SingleTaxAgentAdjustRecordListDTO>>(user).run(getSalaryArchiveTaxAgentWrapper(user)::singleTaxAgentAdjustRecordList, queryParam);
    }

    /**
     * 导出个税扣缴义务人调整记录列表
     *
     * @return
     */
    @GET
    @Path("/adjustRecord/exportTaxAgentList")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response exportTaxAgentList(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        try {
            User user = HrmUserVarify.getUser(request, response);

            TaxAgentAdjustRecordQueryParam param = new TaxAgentAdjustRecordQueryParam();

            XSSFWorkbook workbook = getSalaryArchiveTaxAgentWrapper(user).exportAdjustRecordList(param);

            String fileName = "个税扣缴义务人调整记录" + LocalDate.now();

            try {
                fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            StreamingOutput output = outputStream -> {
                workbook.write(outputStream);
                outputStream.flush();
            };

            response.setContentType("application/octet-stream");
            return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build();

        } catch (Exception e) {
            log.error("个税扣缴义务人调整记录导出异常", e);
            throw e;
        }

    }


    /******** 个税扣缴义务人调整记录 end ***********************************************************************************************/


    @GET
    @Path("/handleRepeatData")
    @Produces(MediaType.APPLICATION_JSON)
    public String SingleTaxAgentAdjustRecordList(@Context HttpServletRequest request, @Context HttpServletResponse response) {
        User user = HrmUserVarify.getUser(request, response);
        return new ResponseResult<String, Map<String, Object>>(user).run(getSalaryArchiveWrapper(user)::handleRepeatData);
    }

}
